package com.joint.web.action.finance;

import com.fz.us.base.bean.BaseEnum;
import com.fz.us.base.bean.Pager;
import com.fz.us.base.util.LogUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.joint.base.bean.FlowEnum;
import com.joint.base.entity.*;
import com.joint.base.exception.users.DutyNotExistsException;
import com.joint.base.exception.workflow.PcfgNotExistException;
import com.joint.base.service.DepartmentService;
import com.joint.base.util.DataUtil;
import com.joint.core.entity.finance.Finance;
import com.joint.core.service.FinanceService;
import com.joint.web.action.BaseFlowAction;
import net.sf.json.JSONObject;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.ParentPackage;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by ZhuChunXiao on 2017/3/2.
 */
@ParentPackage("finance")
public class AjaxFinanceAction extends BaseFlowAction {
    @Resource
    private DepartmentService departmentService;
    @Resource
    private FinanceService financeService;

    private Finance finance;
    private int numStatus;
    private Users loginUser;
    private int ifCentralStaff;

    private String viewtype;
    private String liabilitiefileId;
    private String profitLossfileId;
    private String receivablesfileId;
    private String otherReceivablesfileId;
    private String paymentfileId;
    private String otherPaymentfileId;
    private String costfileId;
    private String liabilitieIds;
    private String profitLossIds;
    private String receivablesIds;
    private String otherReceivablesIds;
    private String paymentIds;
    private String otherPaymentIds;
    private String costIds;
    private String yearId;
    private String monthId;
    private String departmentId;
    private int year;

    public String execute(){
        return "finance";
    }

    public String list(){
        pager = new Pager();
        if (rows <= 0){
            rows = 10;
        }
        pager.setPageSize(rows);
        pager.setPageNumber(page);
        pager.setOrderBy("createDate");
        pager.setOrderType(BaseEnum.OrderType.desc);

        if(StringUtils.isNotEmpty(sidx)&& BaseEnum.OrderType.valueOf(sord)!=null){
            pager.setOrderBy(sidx);
            pager.setOrderType(BaseEnum.OrderType.valueOf(sord));
        }
        Company com = usersService.getCompanyByUser();

        Map<String,Object> params = new HashMap<String,Object>();
        params = getSearchFilterParams(_search,params,filters);
        params.put("company",com);
        params.put("state", BaseEnum.StateEnum.Enable);
        //所有单子
        params.put("processState", new FlowEnum.ProcessState []{FlowEnum.ProcessState.Running, FlowEnum.ProcessState.Backed, FlowEnum.ProcessState.Finished, FlowEnum.ProcessState.Deny});
        pager=financeService.findByPagerAndLimit(true, "finance", pager, params);
        List<Finance> financeList;
        if (pager.getTotalCount() > 0){
            financeList = (List<Finance>) pager.getList();
        }else{
            financeList = new ArrayList<>();
        }
        List<JSONObject> dataRows=new ArrayList<JSONObject>();
        Map<String, Object> data = new HashMap<String, Object>();
        Map<String,Object> rMap;
        for(Finance finance:financeList){
            String state=finance.getProcessState().name();
            rMap = new HashMap<String,Object>();
            rMap.put("id",finance.getId());
            rMap.put("year",finance.getYear());
            rMap.put("month",finance.getMonth());
            rMap.put("department",finance.getDepartment().getName());
            rMap.put("state", finance.getProcessState().value());
            JSONObject o = JSONObject.fromObject(rMap);
            dataRows.add(o);
        }
        data.put("dataRows",dataRows);
        data.put("page",page);
        data.put("rows",rows);
        long recordsNum = pager.getTotalCount();
        data.put("total",calcPageNum(recordsNum));
        data.put("records", recordsNum);

        return  ajaxJson(JSONObject.fromObject(data).toString());
    }

    public String input(){
        year= Calendar.getInstance().get(Calendar.YEAR);
        if (StringUtils.isNotEmpty(keyId)){
            liabilitiefileId="";
            profitLossfileId="";
            receivablesfileId="";
            otherReceivablesfileId="";
            paymentfileId="";
            otherPaymentfileId="";
            costfileId="";
            finance = financeService.get(keyId);
            if(finance.getLiabilitie() != null && finance.getLiabilitie().size()>0){
                for(FileManage f:finance.getLiabilitie()){
                    liabilitiefileId+=f.getId()+",";
                }
            }
            if(finance.getProfitLoss() != null && finance.getProfitLoss().size()>0){
                for(FileManage f:finance.getProfitLoss()){
                    profitLossfileId+=f.getId()+",";
                }
            }
            if(finance.getReceivables() != null && finance.getReceivables().size()>0){
                for(FileManage f:finance.getReceivables()){
                    receivablesfileId+=f.getId()+",";
                }
            }
            if(finance.getOtherReceivables() != null && finance.getOtherReceivables().size()>0){
                for(FileManage f:finance.getOtherReceivables()){
                    otherReceivablesfileId+=f.getId()+",";
                }
            }
            if(finance.getPayment() != null && finance.getPayment().size()>0){
                for(FileManage f:finance.getPayment()){
                    paymentfileId+=f.getId()+",";
                }
            }
            if(finance.getOtherPayment() != null && finance.getOtherPayment().size()>0){
                for(FileManage f:finance.getOtherPayment()){
                    otherPaymentfileId+=f.getId()+",";
                }
            }
            if(finance.getCost() != null && finance.getCost().size()>0){
                for(FileManage f:finance.getCost()){
                    costfileId+=f.getId()+",";
                }
            }
        }

        return "input";
    }

    public String getDefaultDept(){
        Map<String, Object> data = new HashMap<String, Object>();
        Duty duty = dutyService.get(curDutyId);
        data.put("department",duty.getDepartment().getName());
        data.put("departmentId",duty.getDepartment().getId());
        return  ajaxJson(JSONObject.fromObject(data).toString());
    }

    public void setData(){
        if(StringUtils.isNotEmpty(keyId)){
            finance = financeService.get(keyId);
        }else{
            finance = new Finance();
            finance.setCreater(usersService.getLoginInfo());
        }
        finance.setYear(yearId);
        finance.setMonth(monthId);
        finance.setDepartment(departmentService.get(departmentId));
        finance.setCompany(usersService.getLoginInfo().getCompany());

        List<FileManage> liabilitiefileList = Lists.newArrayList();
        if(StringUtils.isNotEmpty(liabilitieIds)){
            for(String f:liabilitieIds.split(",")){
                liabilitiefileList.add(fileManageService.get(f.trim()));
            }
            finance.setLiabilitie(liabilitiefileList);
        }


        List<FileManage> profitLossfileList = Lists.newArrayList();
        if(StringUtils.isNotEmpty(profitLossIds)){
            for(String f:profitLossIds.split(",")){
                profitLossfileList.add(fileManageService.get(f.trim()));
            }
            finance.setProfitLoss(profitLossfileList);
        }

        List<FileManage> receivablesfileList = Lists.newArrayList();
        if(StringUtils.isNotEmpty(receivablesIds)){
            for(String f:receivablesIds.split(",")){
                receivablesfileList.add(fileManageService.get(f.trim()));
            }
            finance.setReceivables(receivablesfileList);
        }

        List<FileManage> otherReceivablesfileList = Lists.newArrayList();
        if(StringUtils.isNotEmpty(otherReceivablesIds)){
            for(String f:otherReceivablesIds.split(",")){
                otherReceivablesfileList.add(fileManageService.get(f.trim()));
            }
            finance.setOtherReceivables(otherReceivablesfileList);
        }

        List<FileManage> paymentfileList = Lists.newArrayList();
        if(StringUtils.isNotEmpty(paymentIds)){
            for(String f:paymentIds.split(",")){
                paymentfileList.add(fileManageService.get(f.trim()));
            }
            finance.setPayment(paymentfileList);
        }

        List<FileManage> otherPaymentfileList = Lists.newArrayList();
        if(StringUtils.isNotEmpty(otherPaymentIds)){
            for(String f:otherPaymentIds.split(",")){
                otherPaymentfileList.add(fileManageService.get(f.trim()));
            }
            finance.setOtherPayment(otherPaymentfileList);
        }
        List<FileManage> costfileList = Lists.newArrayList();
        if(StringUtils.isNotEmpty(costIds)){
            for(String f:costIds.split(",")){
                costfileList.add(fileManageService.get(f.trim()));
            }
            finance.setCost(costfileList);
        }
    }

    public String save(){
        setData();
        try {
            if(StringUtils.isNotEmpty(keyId)){
                financeService.update(finance);
            } else {
                Map<String, Object> various = new HashMap<String, Object>();
                various.put("numStatus", 0);
                various.put("initDuty", curDutyId);
                various.put("curDutyId", curDutyId);
                financeService.save(finance, "finance", various);
            }
        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }

        return ajaxHtmlCallback("200", "保存成功！", "操作状态");
    }

    public String read(){
        loginUser = usersService.getLoginInfo();
        if(StringUtils.isNotEmpty(keyId)){
            numStatus = workflowService.getNumStatus(keyId, loginUser);
            finance=financeService.get(keyId);
            liabilitiefileId="";
            profitLossfileId="";
            receivablesfileId="";
            otherReceivablesfileId="";
            paymentfileId="";
            otherPaymentfileId="";
            costfileId="";
            if(finance.getLiabilitie()!=null&&finance.getLiabilitie().size()>0){
                for(FileManage l:finance.getLiabilitie()){
                    liabilitiefileId+=l.getId()+",";
                }
            }
            if(finance.getProfitLoss()!=null&&finance.getProfitLoss().size()>0){
                for(FileManage p:finance.getProfitLoss()){
                    profitLossfileId+=p.getId()+",";
                }
            }
            if(finance.getReceivables()!=null&&finance.getReceivables().size()>0){
                for(FileManage r:finance.getReceivables()){
                    receivablesfileId+=r.getId()+",";
                }
            }
            if(finance.getOtherReceivables()!=null&&finance.getOtherReceivables().size()>0){
                for(FileManage o:finance.getOtherReceivables()){
                    otherReceivablesfileId+=o.getId()+",";
                }
            }
            if(finance.getPayment()!=null&&finance.getPayment().size()>0){
                for(FileManage p:finance.getPayment()){
                    paymentfileId+=p.getId()+",";
                }
            }
            if(finance.getOtherPayment()!=null&&finance.getOtherPayment().size()>0){
                for(FileManage o:finance.getOtherPayment()){
                    otherPaymentfileId+=o.getId()+",";
                }
            }
            if(finance.getCost()!=null&&finance.getCost().size()>0){
                for(FileManage c:finance.getCost()){
                    costfileId+=c.getId()+",";
                }
            }

        }
        return "read";
    }

    public String commit(){
        Company company = usersService.getCompanyByUser();
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("processState", new FlowEnum.ProcessState[]{FlowEnum.ProcessState.Finished,FlowEnum.ProcessState.Running});
        params.put("year", yearId);
        params.put("month", monthId);
        List<Finance> list = (List<Finance>)financeService.findByPagerAndCompany(null, null, company, params).getList();
        if(list.size()>0){
            return ajaxHtmlCallback("400", "每个月只能新建一次", "操作状态");
        }
        ifCentralStaff=0;
        setData();
        Map<String, Object> var1 = new HashMap<String, Object>();
        var1.put("numStatus", 0);
        var1.put("curDutyId", curDutyId);
        var1.put("initDuty", curDutyId);
        Map<String, Object> var2 = new HashMap<String, Object>();
//        var2.put("numStatus", 1);
//        var2.put("curDutyId", curDutyId);

        Set<Duty> dutySet = usersService.getLoginInfo().getDutySet();
        for (Duty duty:dutySet){
            if(duty.getDepartment().getParent()!=null){
                LogUtil.info("ceshi"+duty.getDepartment().getParent().getName());
                if(StringUtils.equals(duty.getDepartment().getParent().getName(),"产业中心")){
                    ifCentralStaff=1;
                    break;
                }
            }
        }
        if(ifCentralStaff==1){
            var1.put("numStatus",3);
            var2.put("numStatus",3);
        }else{
            var1.put("numStatus",1);
            var2.put("numStatus",1);
        }
        var2.put("curDutyId", curDutyId);
        var2.put("ifCentralStaff", ifCentralStaff);

//        Set<Duty> dutySet=usersService.getLoginInfo().getDutySet();
        List<String> list1=Lists.newArrayList();
        for(Duty duty:dutySet){
            Department dept=duty.getDepartment().getParent()==null?duty.getDepartment():duty.getDepartment().getParent();
            Set<Department> deptSet=dept.getChildren();
            for(Department cdept:deptSet){
                if(cdept.getName().contains("财务科")){
                    Set<Power> powers = cdept.getPowerSet();
                    for(Power power:powers){
                        if(power.getPost().getName().equals("科长")){
                            List<Users> usersList=dutyService.getPersons(cdept,power.getPost());
                            for(Users user:usersList){
                                list1.add(user.getId().trim());
                            }
                        }
                    }
                }

            }
        }
        var1.put("approver", list1);
        var2.put("approver", list1);
        List<String> list2=Lists.newArrayList();
        for(Duty duty:dutySet){
            Department dept=duty.getDepartment().getParent()==null?duty.getDepartment():duty.getDepartment().getParent();
            Set<Power> powers = dept.getPowerSet();
            for(Power power:powers){
                if(power.getPost().getName().equals("总经理")){
                    List<Users> usersList=dutyService.getPersons(dept,power.getPost());
                    for(Users user:usersList){
                        list2.add(user.getId().trim());
                    }
                }
            }
        }
        var1.put("approver1", list2);
        var2.put("approver1", list2);

        try {
            if (StringUtils.isNotEmpty(keyId)) {
                financeService.approve(finance, FlowEnum.ProcessState.Running, var2, curDutyId,comment);
            } else {
                keyId = financeService.commit(finance, "finance", var1, var2, curDutyId);
            }
        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }

        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
    }


    //审批
    public String approve1(){
        ifCentralStaff=0;
        finance = financeService.get(keyId);
        Map<String, Object> var1 = new HashMap<String, Object>();

        Set<Duty> dutySet = usersService.getLoginInfo().getDutySet();
        for (Duty duty:dutySet){
            if(duty.getDepartment().getParent()!=null){
                LogUtil.info("ceshi"+duty.getDepartment().getParent().getName());
                if(StringUtils.equals(duty.getDepartment().getParent().getName(),"产业中心")){
                    ifCentralStaff=1;
                    break;
                }
            }
        }
        var1.put("numStatus", 2);
        var1.put("curDutyId", curDutyId);

        if(StringUtils.isEmpty(comment)){
            comment="";
        }
        try {
            if (StringUtils.isNotEmpty(keyId)) {
                financeService.approve(finance, FlowEnum.ProcessState.Running, var1, curDutyId, comment);
            }
        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }
        catch (Exception e){
            return ajaxHtmlCallback("404", "操作异常，请联系管理员！", "操作状态");
        }
        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
    }

    public String approve2() {
        if(StringUtils.isEmpty(keyId))return ajaxHtmlCallback("404", "文档ID未找到！", "操作状态");
        if(StringUtils.isEmpty(comment)) comment="";
        finance = financeService.get(keyId);

        Map<String, Object> var2 = new HashMap<String, Object>();
        var2.put("numStatus", 3);
        //  var2.put("curDutyId", curDutyId);
        try {
            financeService.approve(finance, FlowEnum.ProcessState.Running, var2, curDutyId,comment);

        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }catch (Exception e){
            return ajaxHtmlCallback("404", "操作异常，请联系管理员！", "操作状态");
        }
        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
    }

    public String approve3() {
        if(StringUtils.isEmpty(keyId))return ajaxHtmlCallback("404", "文档ID未找到！", "操作状态");
        if(StringUtils.isEmpty(comment)) comment="";
        finance = financeService.get(keyId);

        Map<String, Object> var2 = new HashMap<String, Object>();
        var2.put("numStatus", 4);
        //  var2.put("curDutyId", curDutyId);
        try {
            financeService.approve(finance, FlowEnum.ProcessState.Running, var2, curDutyId,comment);
        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }catch (Exception e){
            return ajaxHtmlCallback("404", "操作异常，请联系管理员！", "操作状态");
        }
        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
    }

    public String approve4() {
        if(StringUtils.isEmpty(keyId))return ajaxHtmlCallback("404", "文档ID未找到！", "操作状态");
        if(StringUtils.isEmpty(comment)) comment="";
        finance = financeService.get(keyId);

        Map<String, Object> var2 = new HashMap<String, Object>();
        var2.put("numStatus", 5);
        //  var2.put("curDutyId", curDutyId);
        try {
            financeService.approve(finance, FlowEnum.ProcessState.Finished, var2, curDutyId,comment);
        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }catch (Exception e){
            return ajaxHtmlCallback("404", "操作异常，请联系管理员！", "操作状态");
        }
        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
    }

    /**
     * 退回
     * @return
     */
    public String reject() {
        if (com.joint.base.util.StringUtils.isNotEmpty(keyId)) {
            finance = financeService.get(keyId);
            List<ActivityImpl> activityList= workflowService.findAllActivitiesByKey("finance");
            String key=activityList.get(0).getId();
            System.out.println("Activity key:"+key);
            System.out.println("comment:"+comment);
            LogUtil.info("numStatus:" + numStatus);
            if(StringUtils.isEmpty(comment)) comment="";
            financeService.reject(finance, key, numStatus, comment, curDutyId);
        }
        return ajaxHtmlCallback("200", "退回成功！", "操作状态");
    }

    /**
     * 否决
     * @return
     */
    public String deny() {
        if (com.joint.base.util.StringUtils.isNotEmpty(keyId)) {
            finance = financeService.get(keyId);
            List<ActivityImpl> activityList= workflowService.findAllActivitiesByKey("finance");
            String key= activityList.get(activityList.size()-1).getId();
            System.out.println("Activity key:" + key);
            if(com.joint.base.util.StringUtils.isEmpty(comment)){
                comment="";
            }
            financeService.deny(finance, key, comment, curDutyId);
        }
        return ajaxHtmlCallback("200", "否决成功！", "操作状态");
    }

    @Override
    public int getNumStatus() {
        return numStatus;
    }

    @Override
    public void setNumStatus(int numStatus) {
        this.numStatus = numStatus;
    }

    public String getViewtype() {
        return viewtype;
    }

    public void setViewtype(String viewtype) {
        this.viewtype = viewtype;
    }

    public Finance getFinance() {
        return finance;
    }

    public void setFinance(Finance finance) {
        this.finance = finance;
    }

    public String getLiabilitiefileId() {
        return liabilitiefileId;
    }

    public void setLiabilitiefileId(String liabilitiefileId) {
        this.liabilitiefileId = liabilitiefileId;
    }

    public String getProfitLossfileId() {
        return profitLossfileId;
    }

    public void setProfitLossfileId(String profitLossfileId) {
        this.profitLossfileId = profitLossfileId;
    }

    public String getReceivablesfileId() {
        return receivablesfileId;
    }

    public void setReceivablesfileId(String receivablesfileId) {
        this.receivablesfileId = receivablesfileId;
    }

    public String getOtherReceivablesfileId() {
        return otherReceivablesfileId;
    }

    public void setOtherReceivablesfileId(String otherReceivablesfileId) {
        this.otherReceivablesfileId = otherReceivablesfileId;
    }

    public String getPaymentfileId() {
        return paymentfileId;
    }

    public void setPaymentfileId(String paymentfileId) {
        this.paymentfileId = paymentfileId;
    }

    public String getOtherPaymentfileId() {
        return otherPaymentfileId;
    }

    public void setOtherPaymentfileId(String otherPaymentfileId) {
        this.otherPaymentfileId = otherPaymentfileId;
    }

    public String getCostfileId() {
        return costfileId;
    }

    public void setCostfileId(String costfileId) {
        this.costfileId = costfileId;
    }

    public String getYearId() {
        return yearId;
    }

    public void setYearId(String yearId) {
        this.yearId = yearId;
    }

    public String getMonthId() {
        return monthId;
    }

    public void setMonthId(String monthId) {
        this.monthId = monthId;
    }

    public String getDepartmentId() {
        return departmentId;
    }

    public void setDepartmentId(String departmentId) {
        this.departmentId = departmentId;
    }

    public Users getLoginUser() {
        return loginUser;
    }

    public void setLoginUser(Users loginUser) {
        this.loginUser = loginUser;
    }

    public int getIfCentralStaff() {
        return ifCentralStaff;
    }

    public void setIfCentralStaff(int ifCentralStaff) {
        this.ifCentralStaff = ifCentralStaff;
    }

    public String getCostIds() {
        return costIds;
    }

    public void setCostIds(String costIds) {
        this.costIds = costIds;
    }

    public String getLiabilitieIds() {
        return liabilitieIds;
    }

    public void setLiabilitieIds(String liabilitieIds) {
        this.liabilitieIds = liabilitieIds;
    }

    public String getProfitLossIds() {
        return profitLossIds;
    }

    public void setProfitLossIds(String profitLossIds) {
        this.profitLossIds = profitLossIds;
    }

    public String getReceivablesIds() {
        return receivablesIds;
    }

    public void setReceivablesIds(String receivablesIds) {
        this.receivablesIds = receivablesIds;
    }

    public String getOtherReceivablesIds() {
        return otherReceivablesIds;
    }

    public void setOtherReceivablesIds(String otherReceivablesIds) {
        this.otherReceivablesIds = otherReceivablesIds;
    }

    public String getPaymentIds() {
        return paymentIds;
    }

    public void setPaymentIds(String paymentIds) {
        this.paymentIds = paymentIds;
    }

    public String getOtherPaymentIds() {
        return otherPaymentIds;
    }

    public void setOtherPaymentIds(String otherPaymentIds) {
        this.otherPaymentIds = otherPaymentIds;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }
}
